#pragma once
#include "base/Macro.hpp"

class CellCommon {
public:
    static void cellToVector(std::vector<uint8_t> &row,std::vector<Cell> &cells,uint8_t * beginMemoryAddress,uint32_t &offset){
//        size_t offset = 0;
        for (Cell cell:cells) {
            switch (cell.type) {
                case FieldType::INT:{
                    memcpy(beginMemoryAddress + offset, &cell.i64, INT_64_SIZE);
                    offset += INT_64_SIZE;
                    break;
                }
                case FieldType::STRING:{
//                    const uint8_t* p = reinterpret_cast<const uint8_t*>(&cell.strlen);
                    uint32_t len = static_cast<uint32_t>(cell.str.length());
                    memcpy(beginMemoryAddress + offset,&len,INT_32_SIZE);
                    offset += INT_32_SIZE;
                    memcpy(beginMemoryAddress + offset,cell.str.data(),cell.str.length());
                    offset += cell.str.length();
                    const char * str = "\0";
                    memcpy(beginMemoryAddress + offset,&str,1);
                    offset+=1;
                    break;
                }
                case FieldType::DATETIME:{
                    memcpy(beginMemoryAddress + offset, &cell.datetime, DATETIME_SIZE);
                    offset += DATETIME_SIZE;
                    break;
                }
            }
        }
    }

    static size_t vectorToCell(std::vector<Cell> &cells,std::vector<uint8_t> &row,std::vector<FieldInfo> &fieldList,uint8_t * beginMemoryAddress){
        cells.resize(fieldList.size());
        size_t offset = 0;
//        size_t i = 0;
//        for (FieldInfo fieldInfo: fieldList) {
        for (int i = 0; i < fieldList.size(); ++i) {
            size_t currentSize= offset;
            FieldInfo fieldInfo = fieldList.at(i);
            Cell cell{};
            switch (fieldInfo.type) {
                case FieldType::INT:{
                    cell.type = FieldType::INT;
                    memcpy(&cell.i64,beginMemoryAddress + offset,INT_64_SIZE);
                    offset += INT_64_SIZE;
                    break;
                }
                case FieldType::STRING:{
                    cell.type = FieldType::STRING;
                    uint32_t size = 0;
                    memcpy(&size,beginMemoryAddress + offset,INT_32_SIZE);
                    offset += INT_32_SIZE;
                    cell.str.resize(size);
                    memcpy(cell.str.data(),beginMemoryAddress + offset,size);
                    offset += size + 1;
                    break;
                }
                case FieldType::DATETIME:{
                    cell.type = FieldType::DATETIME;
                    memcpy(&cell.datetime,beginMemoryAddress+offset,DATETIME_SIZE);
                    offset += DATETIME_SIZE;
                }
            }
            cells.at(i) = cell;
//            memcpy(cells.data() + offset,&cell,offset - currentSize);
//            i++;
//            cells.push_back(cell);
        }
        return offset;
    }

    static uint32_t findFieldPrimaryIndex(std::vector<FieldInfo> &fieldList){
        for (uint32_t i = 0; i < fieldList.size(); ++i) {
            if(fieldList.at(i).isPrimary){
                return i;
            }
        }
        std::cerr << "findFieldPrimaryIndex index is null " << std::endl;
        return -1;
    }

};